package com.katze.boot.common.exception;

import com.katze.boot.plugins.redis.exception.LimitAccessException;
import com.katze.common.Message;
import com.katze.common.ResponseStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;

import java.io.IOException;

@RestControllerAdvice
@Order(value = Ordered.HIGHEST_PRECEDENCE)
public class GlobalExceptionHandler {
    private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    // 开启全局异常处理，导致AccessDeniedHandler，AuthenticationEntryPoint（仅限登录时出现异常会被拦截）无法正常使用
    @ExceptionHandler({AccessDeniedException.class, AuthenticationException.class})
    public void handleSecurityException(RuntimeException e) {
        throw e;
    }

    @ExceptionHandler({BusinessException.class})
    public ResponseEntity<Message> handleBusinessException(BusinessException e) {
        log.error("系统内部业务异常，异常信息：", e);
        return ResponseEntity.status(ResponseStatus.OK.value()).body(Message.exception(ResponseStatus.INTERNAL_SERVER_ERROR, e.getMessage()));
    }

    @ExceptionHandler({IOException.class})
    public ResponseEntity<Message> handleIOException(IOException e) {
        if (log.isDebugEnabled()) {
            log.error("系统IO异常, 异常信息: ", e);
        } else {
            log.error("系统IO异常, 异常信息: {}", e.getMessage());
        }
        return ResponseEntity.status(ResponseStatus.OK.value()).body(Message.exception(ResponseStatus.INTERNAL_SERVER_ERROR, e.getMessage()));
    }

    @ExceptionHandler({Exception.class})
    public ResponseEntity<Message> handleException(Exception e) {
        log.error("系统内部异常，异常信息：", e);
        return ResponseEntity.status(ResponseStatus.OK.value()).body(Message.exception(ResponseStatus.INTERNAL_SERVER_ERROR, e.getMessage()));
    }

    @ExceptionHandler(value = HttpRequestMethodNotSupportedException.class)
    public ResponseEntity<Message> handleHttpRequestMethodNotSupportedException(Exception e) {
        log.error("HTTP请求方式不被支持：", e);
        return ResponseEntity.status(ResponseStatus.OK.value()).body(Message.exception(ResponseStatus.METHOD_NOT_ALLOWED));
    }

    @ExceptionHandler(value = NoHandlerFoundException.class)
    public ResponseEntity<Message> handleNoHandlerFoundException(Exception e) {
        log.error("HTTP请求内容未找到：", e);
        return ResponseEntity.status(ResponseStatus.OK.value()).body(Message.exception(ResponseStatus.NOT_FOUND));
    }

    @ExceptionHandler(value = LimitAccessException.class)
    public ResponseEntity<Message> handleLimitAccessException(LimitAccessException e) {
        log.error(e.getMessage());
        return ResponseEntity.status(ResponseStatus.OK.value()).body(Message.exception(ResponseStatus.TOO_MANY_REQUESTS, e.getMessage()));
    }
}
